/*
 * iPersonaPuerta.cpp
 *
 *  Created on: 07/07/2014
 *      Author: migue
 */

#include "iPersonaPuerta.h"
#include "../comun/ServidorIDs.h"
#include "../comun/ServidorRemoto.h"
#include "../defines.h"

#include <syslog.h>
#include <stdio.h>
#include <unistd.h>


iPersonaPuerta::iPersonaPuerta(int numPuerta) :
_cEnvio(RUTA, COLASISTEMA), _cRecibo(RUTA, COLARECIBO_CLI)
{
	//ServidorIDs serv;
	_numPuerta = numPuerta;
	_mtypePuerta = -1;
	_idBroker = -1;

}

void iPersonaPuerta::lanzarCorteDeColas() {
	char arg[20];

	int pid;

	sprintf(arg, "%i", _mtypePuerta);

	pid = fork();
	if (pid == 0) {
		execl("./conexBrokerCliente", "conexBrokerCliente", arg, "E", NULL);
		syslog(LOG_ERR, "Error al lanzar proceso de conexion con Broker, Puerta: %i ", _numPuerta);
		exit(EXIT_FAILURE);
	}

	pid = fork();
	if (pid == 0) {
		execl("./conexBrokerCliente", "conexBrokerCliente", arg, "R", NULL);
		syslog(LOG_ERR, "Error al lanzar proceso de conexion con Broker, Puerta: %i ", _numPuerta);
		exit(EXIT_FAILURE);
	}
}

iPersonaPuerta::~iPersonaPuerta() {

}


int iPersonaPuerta::esperarArrivoDePersona() {
	comprobarIDEntrada();

	MENSAJE msj;

	//_cola.recibir((void*) &msj, TAM_MENSAJE, _mtypePuerta);
	//_cRecibo.recibir((void*) &msj, TAM_MENSAJE, _mtypePuerta);
	_cRecibo.recibirMensaje(msj, Tipos::MSJ_ENTRAR_A_PARQUE, _mtypePuerta);

	if (msj.tipo != Tipos::MSJ_ENTRAR_A_PARQUE) {
		syslog(LOG_ERR, "ERROR Recibida peticion de Ingreso CON TIPO INCORRECTO (esperado: %i, llego: %i) de Persona(id_origen:%li; dest: %li ; destFinal: %li) por la Puerta de Entrada(N°%i,id-%i)",
				(int) Tipos::MSJ_ENTRAR_A_PARQUE ,(int) msj.tipo, msj.origen, msj.destinatario, msj.destinatarioFinal, _numPuerta, _mtypePuerta);
	}
	else {
		syslog(LOG_INFO, "Recibida peticion de Ingreso de Persona(id-%li) por la Puerta de Entrada(N°%i,id-%i)",msj.origen, _numPuerta, _mtypePuerta);
	}

	return msj.origen;
}


/**
 * numTicket = 0 ; Peticion de ingreso al parque negada
 */
void iPersonaPuerta::respuestaDeIngreso(int numTicket, int idPersona) {

	comprobarIDEntrada();

	MENSAJE msj;


	msj.destinatario = _mtypePuerta;
	msj.origen = _mtypePuerta;

	msj.destinatarioFinal = idPersona;
	msj.id = idPersona;



	msj.tipo = Tipos::MSJ_CONFIRMAR_ENTRADA_A_PARQUE;

	msj.respuesta = numTicket;

	//_cola.enviar((void*) &msj, TAM_MENSAJE);
	_cEnvio.enviar((void*) &msj, TAM_MENSAJE);
	syslog(LOG_INFO, "Enviando Confirmacion de Ingreso a Persona(id-%i) por la Puerta de Entrada(N°%i,id-%i)",idPersona, _numPuerta, _mtypePuerta);
}


int iPersonaPuerta::esperarPartidaDePersona() {
	comprobarIDSalida();

	MENSAJE msj;

	//_cRecibo.recibir((void*) &msj, TAM_MENSAJE, _mtypePuerta);
	_cRecibo.recibirMensaje(msj, Tipos::MSJ_SALIR_DE_PARQUE, _mtypePuerta);

	if (msj.tipo != Tipos::MSJ_SALIR_DE_PARQUE) {
		syslog(LOG_ERR, "ERROR TIPO INCORRECTO(esperado: %i, llego: %i ).Recibido Mensaje de Partida de Persona(id_origen:%li, dest: %li, destFinal:%li) por la Puerta de Salida(N°%i,id-%i)",
				(int) Tipos::MSJ_SALIR_DE_PARQUE, (int) msj.tipo, msj.origen, msj.destinatario, msj.destinatarioFinal,_numPuerta, _mtypePuerta);
	}
	else {
		syslog(LOG_INFO, "Recibido Mensaje de Partida de Persona(id-%li) por la Puerta de Salida(N°%i,id-%i)",msj.origen, _numPuerta, _mtypePuerta);
	}

	return msj.origen;
}

void iPersonaPuerta::confirmarPartida(int idPersona) {
	MENSAJE msj;

	comprobarIDSalida();


	msj.origen = _mtypePuerta;
	msj.destinatario = _mtypePuerta;

	msj.destinatarioFinal = idPersona;
	msj.id = idPersona;

	msj.tipo = Tipos::MSJ_CONFIRMAR_SALIDA_DE_PARQUE;

	msj.respuesta = true;

	_cEnvio.enviar((void*) &msj, TAM_MENSAJE);
	syslog(LOG_INFO, "Mensaje enviado a Persona(id-%i) para confirmarPartida por la Puerta de Salida(N°%i,id-%i)",idPersona, _numPuerta, _mtypePuerta);;
}

void iPersonaPuerta::comprobarIDSalida() {
	if (_mtypePuerta == -1) {

		ServidorRemoto serv;
		_mtypePuerta = serv.pedirIdPuerta(_numPuerta, Tipos::PUERTA_SALIDA);
		_idBroker = serv.idBrokerConectado();
	}
}

void iPersonaPuerta::comprobarIDEntrada() {
	if (_mtypePuerta == -1) {

		ServidorRemoto serv;
		_mtypePuerta = serv.pedirIdPuerta(_numPuerta, Tipos::PUERTA_ENTRADA);
		_idBroker = serv.idBrokerConectado();
	}
}

int iPersonaPuerta::idPuerta() {
	return _mtypePuerta;
}

int iPersonaPuerta::idBroker() {
	return _idBroker;
}

void iPersonaPuerta::tipo(Tipos::TipoDePuerta tipo) {
	if (tipo == Tipos::PUERTA_ENTRADA) {
		comprobarIDEntrada();
	}
	else {
		comprobarIDSalida();
	}

	lanzarCorteDeColas();
}
